/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jama.carouselview.views;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Component.DraggedListener;
import ohos.agp.components.DragInfo;
import ohos.agp.components.ListContainer;
import ohos.agp.utils.Point;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;

/**
 * 自定义ListContainer，应当作为嵌套ListContainer的外层ListContainer，已解决滑动冲突（不同方向）
 *
 * @since 2021-04-19
 */
public class BaseListContainer extends ListContainer implements DraggedListener {
    private static final String TAG = BaseListContainer.class.getSimpleName();
    private static final int NUM_3 = 3;
    private float startX;
    private Display display;
    private boolean isFlag = true;
    private int page = 1;
    private CarouselScrollListener carouselScrollListener;

    /**
     * BaseDependentLayout的构造方法，在Java类中new时调用
     *
     * @param context
     */
    public BaseListContainer(Context context) {
        super(context);
        init(context);
    }

    /**
     * BaseDependentLayout的构造方法，在xml布局中
     *
     * @param context
     * @param attrSet
     */
    public BaseListContainer(Context context, AttrSet attrSet) {
        super(context, attrSet);
        init(context);
    }

    /**
     * BaseDependentLayout的构造方法，在xml布局且加Style时调用
     *
     * @param context
     * @param attrSet
     * @param styleName
     */
    public BaseListContainer(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init(context);
    }

    /**
     * scrollToCenter
     *
     * @param position position
     */
    @Override
    public void scrollToCenter(int position) {
        super.scrollToCenter(position);
        int itemPosByVisibleIndex = getItemPosByVisibleIndex(1);
        carouselScrollListener.onScrollStateChanged(this, itemPosByVisibleIndex, position + 1);
    }


    /**
     * getCarouselScrollListener
     *
     * @return CarouselScrollListener
     */
    public CarouselScrollListener getCarouselScrollListener() {
        return carouselScrollListener;
    }

    /**
     * setCarouselScrollListener
     *
     * @param listener listener
     */
    public void setCarouselScrollListener(CarouselScrollListener listener) {
        this.carouselScrollListener = listener;
    }

    private void init(Context context) {
        setDraggedListener(DRAG_HORIZONTAL, this);
        display = DisplayManager.getInstance().getDefaultDisplay(context).get();
        setLongClickable(false);
    }

    /**
     * onDragDown
     *
     * @param component component
     * @param dragInfo  dragInfo
     */
    @Override
    public void onDragDown(Component component, DragInfo dragInfo) {
    }

    /**
     * onDragStart
     *
     * @param component component
     * @param dragInfo  dragInfo
     */
    @Override
    public void onDragStart(Component component, DragInfo dragInfo) {
        Point downPoint = dragInfo.startPoint;
        startX = downPoint.getPointX();
    }

    /**
     * onDragUpdate
     *
     * @param component component
     * @param dragInfo  dragInfo
     */
    @Override
    public void onDragUpdate(Component component, DragInfo dragInfo) {
        scrollBy((int) -dragInfo.xOffset, 0);
    }

    /**
     * onDragEnd
     *
     * @param component component
     * @param dragInfo  dragInfo
     */
    @Override
    public void onDragEnd(Component component, DragInfo dragInfo) {
        if (getVisibleIndexCount() > 0) {
            Point downPoint = dragInfo.updatePoint;
            float mDownX = downPoint.getPointX();
            float gap = startX - mDownX;

            int firstVisibleItemPosition = getFirstVisibleItemPosition();
            int lastVisibleItemPosition = getLastVisibleItemPosition();
            int visibleIndexCount = getVisibleIndexCount();

            // 右
            if (gap < 0 && firstVisibleItemPosition >= 0) {
                Component componentAt = null;
                if (visibleIndexCount != FinalStaticBean.NUM_3) {
                    componentAt = getComponentAt(firstVisibleItemPosition);
                } else {
                    componentAt = getComponentAt(firstVisibleItemPosition + FinalStaticBean.NUM_1);
                }
                float contentPositionX = componentAt.getContentPositionX();
                scrollBy((int) (contentPositionX - display.getAttributes().width / FinalStaticBean.NUM_12)
                        / FinalStaticBean.NUM_10, FinalStaticBean.NUM_0);
                page--;
                if (page < 1) {
                    page = 1;
                }
                carouselScrollListener.onScrollStateChanged(this, firstVisibleItemPosition, page);
            } else {
                // 左
                if (lastVisibleItemPosition > 0) {
                    Component componentAt = null;
                    if (visibleIndexCount != FinalStaticBean.NUM_3) {
                        componentAt = getComponentAt(lastVisibleItemPosition);
                    } else {
                        componentAt = getComponentAt(lastVisibleItemPosition - FinalStaticBean.NUM_1);
                    }
                    float contentPositionX = componentAt.getContentPositionX();
                    scrollBy((int) (contentPositionX - display.getAttributes().width / FinalStaticBean.NUM_12)
                            / FinalStaticBean.NUM_10, FinalStaticBean.NUM_0);
                    page++;
                    if (page > NUM_3) {
                        page = NUM_3;
                    }
                    carouselScrollListener.onScrollStateChanged(this, firstVisibleItemPosition, page);
                }
            }
        }
    }

    /**
     * onDragCancel
     *
     * @param component component
     * @param dragInfo  dragInfo
     */
    @Override
    public void onDragCancel(Component component, DragInfo dragInfo) {
    }

    /**
     * onItemLongClicked
     *
     * @param parent    parent
     * @param component component
     * @param position  position
     * @param id        id
     * @return boolean
     */
    @Override
    protected boolean onItemLongClicked(ListContainer parent, Component component, int position, long id) {
        return false;
    }
}